/*
    Copyright 2006 Andrew Wilkinson <andrew@indiegigs.co.uk>

    This file is part of libgp2x.

    libgp2x is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    libgp2x is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with libgp2x; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/** \brief This file is the main header file for processes running on the second processor.
  *
  * This header file should be included by all processes which will run on the 940t.
  * When this file is included there is no need to also include the file \link gp2x.h gp2x.h \endlink
  */

#ifndef __LIB_GP2X_940_H__
#define __LIB_GP2X_940_H__

#include <stddef.h>
#include <stdio.h>

#define GP2x_940t
#include "gp2x.h"

#ifndef HOST_PC
/** \brief This define should be included once in each process that will run on the 940t
  * \ingroup dualcore
  * To see how to use this, see on the dual core examples.
  */
#define entry_point void _start() __attribute__((naked)); \
void _start() { \
    asm volatile ( \
    "b .entry @ have all the entry points jump to start of the code\n" \
    "b .entry\n" \
    "b .entry\n" \
    "b .entry\n" \
    "b .entry\n" \
    "b .entry\n" \
    "b .entry\n" \
    "b .entry\n" \
    ".entry:\n" \
    "mov sp, #0x100000           @ set the stack top (1M)\n" \
    "sub sp, sp, #4              @ minus 4, just to be tidy\n" \
    ); \
    GP2x_init(GP2x_INIT_ALL); \
}
#else
#define entry_point
#define main GP2x_main
#endif

#ifdef HOST_PC
#define malloc GP2x_malloc
#define free GP2x_free

#ifndef GP2x_INTERNAL
#define memset GP2x_memset
#define memcpy GP2x_memcpy
#define sprintf GP2x_sprintf
#define strlen GP2x_strlen
#define strcpy GP2x_strcpy
#define printf GP2x_printf
#define fprintf GP2x_fprintf
#define puts GP2x_puts
#ifdef stdout
#undef stdout
#endif
#define stdout GP2x_stdout
extern FILE* GP2x_stdout;
#ifdef stderr
#undef stderr
#endif
#define stderr GP2x_stderr
extern FILE* GP2x_stderr;
#define exit GP2x_exit
#endif

#endif

/* Definitions for standard library functions */
/** \brief Sets the memory pointed to by s to the value c.
  * \ingroup dualcorestdlib
  * \param s Pointer to the memory to be set.
  * \param c The byte value which the memory will be filled with.
  * \param n The number of bytes to fill.
  * \return A pointer to the memory that has been filled.
  */
void* memset(void* s, int c, size_t n);

/** \brief Allocates memory.
  * \ingroup dualcorestdlib
  * \param size The size of the memory block to be allocated.
  * \return A pointer to the allocated memory, or 0 if the request could not be fulfilled.
  */
void* malloc(size_t size);
/** \brief Frees memory.
  * \ingroup dualcorestdlib
  * \param ptr A pointer to the memory block being freed.
  */
void free(void* ptr);

void* memcpy(void* dest, const void* src, size_t n);

int sprintf(char* str, const char* fmt, ...);
int printf(const char* fmt, ...);
int fprintf(FILE* fp, const char* fmt, ...);
int puts(const char* s);
size_t strlen(const char* str);
char* strcpy(char* dest, const char* src);

void exit(int code);

#endif
